module div_unit(
  input clk,
  input rst,
  input flush,

  input [7:0] op,
  input [63:0] src1,
  input [63:0] src2,
  input [63:0] imm,
  
  output ready,
  output [63:0] res,
  output valid_o
);
  wire op_DIVUW,op_DIVW,op_REMUW,op_REMW,op_DIV,op_DIVU,op_REMU,op_REM;
  assign {op_DIVUW,op_DIVW,op_REMUW,op_REMW,op_DIV,op_DIVU,op_REMU,op_REM} = op;

  wire op_rem = op_REMUW|op_REMW|op_REMU|op_REM;
  wire op_div = op_DIVUW|op_DIVW|op_DIVU|op_DIV;

  wire op_w = op_REMUW|op_REMW|op_DIVUW|op_DIVW;
  wire op_sign = op_REMW|op_REM|op_DIVW|op_DIV;

  wire [63:0] src1_w = {{32{src1[31]}},src1[31:0]};
  wire [63:0] src2_w = {{32{src2[31]}},src2[31:0]};

  wire [63:0] op_val_1 = {64{op_w}}&src1_w | {64{!op_w}}&src1;
  wire [63:0] op_val_2 = {64{op_w}}&src2_w | {64{!op_w}}&src2;

  wire signed [64:0] div_op_1 = {op_sign&op_val_1[63],op_val_1};
  wire signed [64:0] div_op_2 = {op_sign&op_val_2[63],op_val_2};

  wire signed [64:0] div_res = $signed(div_op_1) / $signed(div_op_2);
  wire signed [64:0] rem_res = $signed(div_op_1) % $signed(div_op_2);

  wire [64:0] res_mid = {65{op_div}}&div_res | {65{op_rem}}&rem_res;
  wire [63:0] res_mid2 = {op_sign&res_mid[64]|!op_sign&res_mid[63],res_mid[62:0]};
  // assign res = {{32{op_w&res_mid2[31]}}|({32{!op_w}}&res_mid2[63:32] ), res_mid2[31:0] };
  assign valid_o = |op;
  // assign ready = 1'b1;

  
  wire valid_i = |op;
  wire op_div_r,op_rem_r;
  Reg #(.WIDTH(2), .RESET_VAL(2'b0)) reg_sel (.clk(clk), .rst(rst|flush), .din({op_div,op_rem}), .dout({op_div_r,op_rem_r}), .wen(valid_i));
  wire [63:0] res_quo,res_rem;

  assign res = {64{op_div_r}}&res_quo | {64{op_rem_r}}&res_rem;

  wire div_valid_o;
  basediv inst_basediv
  (
    .clk        (clk),
    .rst        (rst),
    .valid_i    (valid_i),
    .flush      (flush),
    .divw       (op_w),
    .div_signed (op_sign),
    .src1       (op_val_1),
    .src2       (op_val_2),
    .ready      (ready),
    .valid_o    (div_valid_o),
    .quotient   (res_quo),
    .remainder  (res_rem)
  );

endmodule
